package com.shb.jutils.commons;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件工具类
 * @author shb
 *
 */
public class FileUtil {
	private FileUtil(){}
	
	/**
	 * 获取文件输入流
	 * @param fPath
	 * @return
	 */
	public static InputStream getInputStream(String fPath){
		InputStream in = null ;
		File f = new File(fPath);
		if(f.exists() && f.isFile()){
			try {
				in = new FileInputStream(f);
			} catch (FileNotFoundException e) {
				throw new RuntimeException(e);
			}
		}
		return in;
	}
	
	/** 
     * 获得指定文件的byte数组 
     */
	public static byte[] readFile(String fPath){
		byte[] bytes = null;
		FileInputStream fis = null;
		ByteArrayOutputStream bos = null;
		try{
			File file = new File(fPath);
			fis = new FileInputStream(file);
			bos = new ByteArrayOutputStream(1000);
			byte[] b = new byte[1000];
			int n ;
			while((n=fis.read(b)) != -1){
				bos.write(b, 0, n);
			}
			bytes = bos.toByteArray();
		}catch(IOException e){
			throw new RuntimeException(e);
		}finally {
			if(bos != null){
				try {
					bos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if(fis!= null){
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return bytes;
	}
	
	/** 
     * 根据byte数组，生成文件 
     */
	public static void writeFile(byte[] bytes, String dirPath, String fileName){
		BufferedOutputStream bos = null;  
        FileOutputStream fos = null;  
		try{
			File dirFile = new File(dirPath);
			if(!dirFile.exists() || !dirFile.isDirectory()){
				dirFile.mkdir();
			}
			File file = new File(dirPath+"\\"+fileName);  
			fos = new FileOutputStream(file);
			bos = new BufferedOutputStream(fos);
			bos.write(bytes);
		}catch(IOException e){
			throw new RuntimeException(e);
		}finally {
			if(bos != null){
				try {
					bos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fos != null) {  
                try {  
                    fos.close();  
                } catch (IOException e1) {  
                    e1.printStackTrace();  
                }  
            }
		}
	}

	/**
	 * 删除文件
	 * @param fPath
	 * @return
	 */
	public static boolean delFile(String fPath){
		File f = new File(fPath);
		return f.delete();
	}
	
	/**
	 * 遍历文件夹中所有的文件，或返回包含该文件的集合
	 * @param f
	 * @param list
	 * @return
	 */
	private static List<File> findFileList(File f, List<File> list){
		if(f.isFile()){
			list.add(f);
		}else {
			File[] files = f.listFiles();
			for(File file : files){
				findFileList(file, list);
			}
		}
		return list;
	}
	
	/**
	 * 遍历某路径下所有的文件,包括文件夹中所有子文件,不包含文件夹
	 * @param fPath
	 * @return
	 */
	public static List<File> findFileList(String fPath){
		File f = new File(fPath);
		List<File> list = new ArrayList<File>();
		if(f.exists()){
			return findFileList(f, list);
		}
		return list;
	}

	/**
     * 递归删除目标文件夹及其子文件
     * NOTE:当目标是文件时，也会直接删除;当文件不存在时，返回true
     * @param dir
     * @return
     */
	public static boolean delFile(File file){
		if(file.exists()){
			if(file.isDirectory()){
				File[] files = file.listFiles();
				for(File f : files){
					boolean success = delFile(f);
					if(!success){
						return false;
					}
				}
			}
			return file.delete();
		}else{
			return true;
		}
	}
	
	/**
	 * 清空文件夹下所有内容
	 * NOTE: 调用了该类中delFile方法
	 * @param dir
	 * @return
	 */
	public static boolean emptyDir(File dir){
		if(dir.exists() && dir.isDirectory()){
			for(File f : dir.listFiles()){
				if(!delFile(f)){
					return false;
				}
			}
			return true;
		}else{
			throw new RuntimeException("目标文件夹不存在");
		}
	}

	/**
	 * 向文件追加字符串
	 * NOTE: 字符串以UTF-8解码
	 * @param str
	 * @param fPath
	 */
	public static void appendStr(String str, String fPath){
		File f = new File(fPath);
		FileOutputStream fos = null;
		try{
			fos = new FileOutputStream(f);
			fos.write(str.getBytes("utf8"));
		}catch (IOException e) {
			throw new RuntimeException(e);
		}finally {
			if(fos != null){
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
